#!/usr/bin/env bash
# Copyright (c) 2021 maminjie <maminjie2@huawei.com>
# SPDX-License-Identifier: MulanPSL-2.0

method_def pushcode packageinit deleterepo forkrepo createpr commentpr
method_def finddeveloper

__oec_token=""
__oec_id=""
__oec_passwd=""


oec_init() {
    if [ -z "$__oec_token" ]; then
        __oec_token=$(setting_get gitee token)
        gitee_init "$__oec_token"
    fi
    if [ -z "$__oec_id" ]; then
        __oec_id=$(setting_get gitee id)
    fi
}

# oec_checkrepo repo
#   Check personal repo
# Returns:
#   1 - exist
#   0 - nonexist
oec_checkrepo() {
    local git_url="https://gitee.com/$__oec_id/$1"
    local result=$(gitee_get_one_repo "$__oec_id" "$1")
    if [ -n "$result" ]; then
        return 1
    fi
    return 0
}

# gitee_get_contents owner repo path ref
#   Get the content under the specific path of the owner/repo
# Params:
#   path - the file path
#   ref - branch, tag or commit
# Returns:
#   "" or contents
oec_get_contents() {
    oec_init
    gitee_get_contents "$1" "$2" "$3" "$4"
}

# oec_get_branches owner repo
oec_get_branches() {
    oec_init
    gitee_get_branches "$1" "$2"
}

# oec_get_user_repos username
oec_get_user_repos() {
    oec_init
    gitee_get_user_repos "$1"
}

# oec_get_org_repos org
oec_get_org_repos() {
    oec_init
    gitee_get_org_repos "$1"
}

# oec_pushcode comments
oec_pushcode() {
    if [ -z "$__oec_passwd" ]; then
        __oec_passwd=$(setting_get gitee passwd)
        if [ -z "$__oec_passwd" ]; then
            # == read -s -p ...
            stty -echo
            read -p "Password for gitee: " __oec_passwd
            stty echo
        fi
    fi
    git add .
    git commit -m "$1"
    expect -c "
    set timeout -1
    spawn git push
    expect {
    \"*Username*\" {send \"${__oec_id}\r\";exp_continue}
    \"*Password*\" {send \"${__oec_passwd}\r\";exp_continue}
    }
    "
}

# oec_createpr owner repo comments url [branch]
oec_createpr() {
    local branch="$5"
    local curbranch=$(git_curbranch)
    if [ -z "$branch" ]; then
        branch=$curbranch
    fi
    local __pr_url__=""
    gitee_create_pr "$1" "$2" "$3" "$__oec_id" "$curbranch" "$branch" __pr_url__
    eval $4=\"$__pr_url__\"
}

usage_pushcode() {
printf "pushcode (pushc): Auto push code, including push, pr.

Usage:
    ${PROG} pushc owner repo [comments] [branch]

Params:
    owner - The upstream owner of package, as: src-openeuler
    comments - (optional) default is \"Package init\", and as the title of pr
    branch - (optional) target branch, default is current branch of gitrepository

Progress:
    git add .
    git commit -m \"{comments}\"
    git push
    create pr from mine/repo/currentbranch to owner/repo/branch
"
}

alias_def pushcode pushc
# do_pushcode owner repo [comments] [branch]
do_pushcode() {
    if [ $# -lt 2 ]; then
        usage_pushcode; exit
    fi
    local owner=$1
    local repo=$2
    local comments=$3
    local branch=$4
    if [ -z "$comments" ]; then
        comments="Package Init"
    fi
    oec_init
    oec_pushcode "$comments"
    local url=""
    oec_createpr "$owner" "$repo" "$comments" url "$branch"
    if [ -n "$url" ]; then
        echo "$url"
    fi
}


usage_packageinit() {
printf "packageinit (pkginit): Init package to gitee, including fork, clone, push, pr.

Usage:
    ${PROG} pkginit SOURCEDIR TARGETDIR OWNER PKGLIST|LISTFILE [BRANCH]

Params:
    SOURCEDIR - The source directory that contains specific packages
    TARGETDIR - The target directory, where the packages are generally cloned from gitrepo
    OWNER - The upstream owner of package, as: src-openeuler
    PKGLIST - package string list, as: \"pkg1 pkg2 pkg3\"
    LISTFILE - A file that contains package list
    BRANCH - (optional) target branch, default is current branch of gitrepository

Examples:
    ${PROG} pkginit /home/mine/src /home/mine/dst src-openeuler \"a b\"
                    Submit the two packages a and b to src-openeuler (fork, clone, push, pr).
                    sourcefiles in /home/mine/src and repos are cloned in /home/mine/dst

"
}

# __oec_submitpkg src_dir dst_dir owner repo comments prurl [branch]
# Params
#   prurl - [O] the pr url
#   branch - [I] (optional) target branch
__oec_submitpkg() {
    local src_dir=$1
    local dst_dir=$2
    local owner=$3
    local repo=$4
    local comments="$5"
    local branch="$7"
    local srcpath=$src_dir/$repo
    local dstpath=$dst_dir/$repo

    # clone
    if [ ! -d $dstpath ]; then
        pushd "$dst_dir" || exit 1
        git clone https://gitee.com/$__oec_id/$repo.git
        popd || exit 1
    fi

    if [ ! -d $srcpath ] || [ ! -d $dstpath ]; then
        exit 2
    fi

    pushd "$dstpath" || exit
    git checkout openEuler-22.03-LTS-Next
    rm -rf "$dstpath"/*
    cp "$srcpath"/* "$dstpath"
    oec_pushcode "$comments"
    local __prurl__=""
    oec_createpr "$owner" "$repo" "$comments" __prurl__ "$branch"
    eval $6=\"$__prurl__\"
    popd || exit
}

alias_def packageinit pkginit
# do_packageinit src_dir dst_dir owner repo_list [branch]
do_packageinit() {
    if [ $# -lt 4 ]; then
        usage_packageinit; exit
    fi
    local src_dir=$1
    local dst_dir=$2
    local owner=$3
    local repo_list=$(get_list "$4")
    local branch="$5"
    local prurls=()

    if [ -n "$repo_list" ]; then
        oec_init
    fi

    for pkg in $repo_list; do
        oec_checkrepo "$pkg"
        if [ $? -eq 0 ]; then
            echo -n "forking $pkg: "
            gitee_fork_repo "$owner" "$pkg"
            if [ $? -ne 0 ]; then
                color_print "$CLR_RED" "failed"
                continue
            else
                color_print "$CLR_GREEN" "success"
            fi
        fi
        sleep 2
        local prurl=""
        __oec_submitpkg "$src_dir" "$dst_dir" "$owner" "$pkg" "remove unuse files" prurl "$branch"
        if [ -n "$prurl" ]; then
            array_add prurls "$prurl"
        fi
        sleep 1
    done
    if [ ${#prurls[@]} -gt 0 ]; then
        echo "----PRs----"
        array_uniq prurls
    fi
}


usage_deleterepo() {
printf "deleterepo (delrepo): Delete the repo of owner from gitee

Usage:
    ${PROG} delrepo owner repos

"
}

alias_def deleterepo delrepo
# do_deleterepo owner repos
do_deleterepo() {
    if [ $# -ne 2 ]; then
        usage_deleterepo; exit
    fi
    local owner=$1
    local repos=$(get_list "$2")

    oec_init
    for repo in $repos; do
        echo -n "delete $owner/$repo: "
        gitee_delete_repo "$owner" "$repo"
        if [ $? -ne 0 ]; then
            color_print "$CLR_RED" "failed"
        else
            color_print "$CLR_GREEN" "success"
        fi
    done
}

usage_forkrepo() {
printf "forkrepo (frepo): Fork the repo from upstream

Usage:
    ${PROG} forkrepo owner repos

"
}

alias_def forkrepo frepo
# do_forkrepo owner repos
do_forkrepo() {
    if [ $# -ne 2 ]; then
        usage_forkrepo; exit
    fi
    local owner=$1
    local repos=$(get_list "$2")

    oec_init
    for repo in $repos; do
        echo -n "forking $repo: "
        oec_checkrepo "$repo"
        if [ $? -eq 0 ]; then
            gitee_fork_repo "$owner" "$repo"
            if [ $? -ne 0 ]; then
                color_print "$CLR_RED" "failed"
                continue
            else
                color_print "$CLR_GREEN" "success"
            fi
        else
            color_print "$CLR_BLUE" "maybe exist"
        fi
    done
}

usage_createpr() {
printf "createpr: Create PR to upstream repo

Usage:
    ${PROG} createpr owner repo title [srcbranch] [dstbranch]

Params:
    xxxbranch - option, if the current directory is a git repository,
                the default is the current branch, otherwise the default is master

"
}

# do_createpr owner repo title [srcbranch] [dstbranch]
do_createpr() {
    if [ $# -lt 3 ]; then
        usage_createpr; exit
    fi
    oec_init
    local owner="$1"
    local repo="$2"
    local title="$3"
    local sbranch="$4"
    local dbranch="$5"
    if [ -z "$sbranch" ]; then
        git_checklocalrepo
        if [ $? -eq 0 ]; then
            sbranch=$(git_curbranch)
        fi
    fi
    if [ -z "$dbranch" ]; then
        dbranch="$sbranch"
    fi
    local __url=""
    gitee_create_pr "$owner" "$repo" "$title" "$__oec_id" "$sbranch" "$dbranch" __url
    if [ -n "$__url" ]; then
        echo "$__url"
    fi
}

usage_commentpr() {
printf "commentpr: Comment pull request

Usage:
    ${PROG} commentpr owner repos number comments
    ${PROG} commentpr urls comments

Params:
    repos - If it is a list (string list or list file) of repositories,
            then all repos use the same number and comments
    urls - pr url list (string list or list file),
            url as: \"https://gitee.com/{owner}/{repo}/pulls/{number}\"

"
}

# __do_commentpr owner repo number comments
__do_commentpr() {
    local owner=$1
    local repo="$2"
    local number="$3"
    local comments="$4"
    echo -n "comment PR $owner/$repo/$number \"$comments\": "
    gitee_set_pr_comment "$owner" "$repo" "$number" "$comments"
    if [ $? -eq 0 ]; then
        color_print "$CLR_GREEN" "success"
    else
        color_print "$CLR_RED" "failed"
    fi
}

# do_commentpr owner repos number comments
# do_commentpr urls comments
do_commentpr() {
    local owner=""
    local number=""
    local comments=""

    oec_init
    if [ $# -eq 2 ]; then
        local urls=$(get_list "$1")
        comments="$2"
        local repo=""
        # https://gitee.com/maminjie/ola/pulls/1
        for url in $urls; do
            eval $(echo "$url" | awk -F "/" '{
                if (NF >= 7) {
                    printf("owner=%s;repo=%s;number=%s;", $(NF-3), $(NF-2), $NF)
                }
            }')
            if [[ -z "$owner" || -z "$repo" || -z "$number" ]]; then
                continue
            fi
            __do_commentpr "$owner" "$repo" "$number" "$comments"
        done
    elif [ $# -eq 4 ]; then
        owner=$1
        local repos=$(get_list "$2")
        number="$3"
        comments="$4"
        for repo in $repos; do
            __do_commentpr "$owner" "$repo" "$number" "$comments"
        done
    else
        usage_commentpr; exit
    fi
}

usage_finddeveloper() {
printf "finddeveloper (fdev): Find the developer of package

usage:
    ${PROG} fdev SPEC
    ${PROG} fdev repo [owner] [branch]

params:
    SPEC - spec file
    owner - (optional) the owner of repo, default is src-openeuler
    branch - (optional) the branch of repo, default is master

"
}

alias_def finddeveloper fdev
# do_finddeveloper spec
# do_finddeveloper repo [owner] [branch]
do_finddeveloper() {
    if [ $# -lt 1 ]; then
        usage_finddeveloper; exit
    fi
    if [ -f "$1" ]; then
        spec_get_developer "$1"
    else
        local repo="$1"
        local owner="$2"
        local branch="$3"
        if [ -z "$owner" ]; then
            owner="src-openeuler"
        fi
        if [ -z "$branch" ]; then
            branch="master"
        fi
        oec_init
        local specdata="$(oec_get_contents "$owner" "$repo" "$repo.spec" "$branch")"
        if [ -z "$specdata" ]; then
            return
        fi
        spec_get_developer "$specdata"
    fi
}

